package cz.muni.fi.pa165.web;

import cz.muni.fi.pa165.api.ForestVisitService;
import cz.muni.fi.pa165.api.PickerService;
import cz.muni.fi.pa165.api.dto.ForestVisitDTO;
import cz.muni.fi.pa165.api.dto.PickerDTO;
import cz.muni.fi.pa165.api.dto.PickerDTO.UserRole;
import cz.muni.fi.pa165.web.validation.PickerDTOValidator;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

/**
 * Controller class for working with Picker
 *
 * @author Matej Cimbora
 */
@Controller
public class PickerController {

    @Autowired
    private PickerService pickerService;
    @Autowired
    private PickerDTOValidator validator;
    @Autowired
    private ForestVisitService forestVisitService;

    @RequestMapping(value = "auth/picker")
    public String initialAdmin(ModelMap modelMap) {
        modelMap.addAttribute("command", new PickerDTO());
        modelMap.addAttribute("pickers", pickerService.findAllPickers());
        return "auth/picker";
    }

    @RequestMapping(value = "/registration")
    public String initialReg(ModelMap modelMap) {
        modelMap.addAttribute("username", "anonymousUser");
        modelMap.addAttribute("command", new PickerDTO());
        modelMap.addAttribute("pickers", pickerService.findAllPickers());
        return "registration";
    }

    @RequestMapping(value = "addPicker")
    public String register(@ModelAttribute("command") PickerDTO picker, BindingResult result, ModelMap modelMap) {
        validator.validate(picker, result);
        if (result.hasErrors()) {
            modelMap.addAttribute("pickers", pickerService.findAllPickers());
            return "registration";
        } else {
            if (picker.getUserRole() == null) {
                picker.setUserRole(PickerDTO.UserRole.ROLE_USER);
            }
            
            pickerService.createPicker(picker);
            modelMap.addAttribute("pickers", pickerService.findAllPickers());
            return "confirmation";

        }
    }

    @RequestMapping(value = "auth/removePicker*")
    public String removeAdmin(@RequestParam("id") String request, ModelMap modelMap) {
        PickerDTO picker = pickerService.getPicker(Long.valueOf(request));
        // remove picker's visits
        for (ForestVisitDTO fv : forestVisitService.retrieveVisitsByPicker(picker)) {
            forestVisitService.removeVisit(fv);
        }
        pickerService.deletePicker(picker);
        modelMap.addAttribute("command", new PickerDTO());
        modelMap.addAttribute("pickers", pickerService.findAllPickers());
        return "auth/picker";
    }

    @RequestMapping(value = "auth/editPicker*")
    public String editAdmin(@RequestParam("id") String request, ModelMap model) {
        PickerDTO picker = pickerService.getPicker(Long.valueOf(request));
        model.addAttribute("command", picker);
        return "auth/editPicker";
    }

    @RequestMapping(value = "auth/editedPicker*")
    public String editedPickerAdmin(@ModelAttribute("command") PickerDTO picker,
            BindingResult result, ModelMap modelMap) {
        validator.validate(picker, result);
        if (result.hasErrors()) {
            modelMap.addAttribute("command", picker);
            return "auth/editPicker";
        } else {
            pickerService.updatePicker(picker);
            modelMap.addAttribute("command", new PickerDTO());
            modelMap.addAttribute("pickers", pickerService.findAllPickers());
            return "auth/picker";
        }
    }

    @RequestMapping(value = "auth/addPicker")
    public String addAdmin(@ModelAttribute("command") PickerDTO picker, BindingResult result, ModelMap modelMap) {
        validator.validate(picker, result);
        if (result.hasErrors()) {
            modelMap.addAttribute("pickers", pickerService.findAllPickers());
            return "auth/picker";
        } else {
            if (picker.getUserRole() == null) {
                picker.setUserRole(PickerDTO.UserRole.ROLE_USER);
            }
            pickerService.createPicker(picker);
            modelMap.addAttribute("pickers", pickerService.findAllPickers());
            return "auth/picker";

        }
    }
    
        @RequestMapping(value="/loginfailed")
	public String loginerror(ModelMap model) {
		model.addAttribute("error", "true");
		return "login";
	}

    @ExceptionHandler(DataAccessException.class)
    public ModelAndView handleException(DataAccessException ex) {

        ModelAndView m = new ModelAndView();
        m.setViewName("picker");
        m.addObject("command", new PickerDTO());
        m.addObject("pickers", pickerService.findAllPickers());
        m.addObject("error", "Error has occured, try again");
        return m;
    }

    @ModelAttribute("roles")
    public List<String> getRoles() {
        List<String> roles = new ArrayList<>();
        for (UserRole role : UserRole.values()) {
            roles.add(role.name());
        }
        return roles;
    }
}
